import sys
import os
import re
import requests
import time
import hashlib
import mimetypes
import json
from urllib.parse import urlparse, unquote
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QHBoxLayout,
                            QPushButton, QFileDialog, QTextEdit, QLabel,
                            QProgressBar, QMessageBox, QDialog, QFormLayout,
                            QSpinBox, QCheckBox, QListWidget, QSplitter,
                            QGroupBox, QGridLayout)
from PyQt5.QtCore import QThread, pyqtSignal, Qt, QTimer
from PyQt5.QtGui import QFont


class Config:
    """配置类"""
    DOWNLOAD_TIMEOUT = 30
    CHUNK_SIZE = 8192
    MAX_RETRIES = 3
    SUPPORTED_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp',
                           '.mp4', '.avi', '.mov', '.wmv', '.mp3', '.wav', '.ogg',
                           '.pdf', '.doc', '.docx', '.txt']
    DELAY_BETWEEN_DOWNLOADS = 0.1
    MAX_FILE_SIZE = 100 * 1024 * 1024  # 100MB

    @classmethod
    def load_from_file(cls, config_path):
        """从配置文件加载设置"""
        try:
            with open(config_path, 'r', encoding='utf-8') as f:
                data = json.load(f)
                cls.DOWNLOAD_TIMEOUT = data.get('download_timeout', cls.DOWNLOAD_TIMEOUT)
                cls.MAX_RETRIES = data.get('max_retries', cls.MAX_RETRIES)
                cls.DELAY_BETWEEN_DOWNLOADS = data.get('delay', cls.DELAY_BETWEEN_DOWNLOADS)
                cls.MAX_FILE_SIZE = data.get('max_file_size', cls.MAX_FILE_SIZE)
        except:
            pass  # 使用默认配置

    @classmethod
    def save_to_file(cls, config_path):
        """保存配置到文件"""
        try:
            data = {
                'download_timeout': cls.DOWNLOAD_TIMEOUT,
                'max_retries': cls.MAX_RETRIES,
                'delay': cls.DELAY_BETWEEN_DOWNLOADS,
                'max_file_size': cls.MAX_FILE_SIZE
            }
            with open(config_path, 'w', encoding='utf-8') as f:
                json.dump(data, f, indent=2)
        except Exception as e:
            print(f"配置保存失败: {e}")


class MediaInfo:
    """媒体信息类"""
    def __init__(self, url, filename, status="待下载", size="未知"):
        self.url = url
        self.filename = filename
        self.status = status
        self.size = size
        self.local_path = ""


class WorkerThread(QThread):
    """后端处理逻辑线程（全面增强版）"""
    log_updated = pyqtSignal(str)
    progress_updated = pyqtSignal(int)
    task_finished = pyqtSignal(str, bool)  # message, success
    media_found = pyqtSignal(list)  # 发现的媒体列表

    def __init__(self, file_paths, preview_only=False):
        super().__init__()
        self.file_paths = file_paths if isinstance(file_paths, list) else [file_paths]
        self.preview_only = preview_only
        self.is_running = True
        self.media_list = []
        self.stats = {'total': 0, 'success': 0, 'failed': 0, 'size': 0}

    def stop(self):
        self.is_running = False

    def extract_media_urls(self, content):
        """提取所有媒体URL的改进版本"""
        patterns = [
            # Markdown 图片语法
            r'!\[.*?\]\((https?://[^\s)]+)\)',
            # HTML img 标签 (各种引号格式)
            r'<img[^>]+src\s*=\s*["\']?(https?://[^"\'\s>]+)["\']?[^>]*>',
            # HTML video 标签
            r'<video[^>]+src\s*=\s*["\']?(https?://[^"\'\s>]+)["\']?[^>]*>',
            # HTML audio 标签
            r'<audio[^>]+src\s*=\s*["\']?(https?://[^"\'\s>]+)["\']?[^>]*>',
            # 直接的媒体链接（常见扩展名）
            r'(https?://[^\s]+\.(?:jpg|jpeg|png|gif|bmp|webp|mp4|avi|mov|wmv|mp3|wav|ogg|pdf|doc|docx|txt)(?:\?[^\s]*)?)',
        ]

        urls = []
        for pattern in patterns:
            matches = re.finditer(pattern, content, re.IGNORECASE)
            for match in matches:
                url = match.group(1) if match.lastindex else match.group(0)
                # 清理URL末尾的标点符号
                url = re.sub(r'[,.\)]+$', '', url)
                urls.append(url)

        return list(set(urls))  # 去重

    def get_extension_from_content_type(self, url):
        """从HTTP头获取文件扩展名"""
        try:
            response = requests.head(url, timeout=5, allow_redirects=True)
            content_type = response.headers.get('content-type', '').split(';')
            ext = mimetypes.guess_extension(content_type)
            return ext if ext else '.bin'
        except:
            return '.bin'

    def get_file_size(self, url):
        """获取文件大小"""
        try:
            response = requests.head(url, timeout=5, allow_redirects=True)
            content_length = response.headers.get('content-length')
            if content_length:
                size = int(content_length)
                return self.format_size(size)
            return "未知"
        except:
            return "未知"

    def format_size(self, size_bytes):
        """格式化文件大小"""
        for unit in ['B', 'KB', 'MB', 'GB']:
            if size_bytes < 1024:
                return f"{size_bytes:.1f} {unit}"
            size_bytes /= 1024
        return f"{size_bytes:.1f} TB"

    def generate_unique_filename(self, url):
        """改进的文件名生成方法"""
        try:
            # 解析URL
            parsed = urlparse(url)
            path = unquote(parsed.path)
            # 提取文件名和扩展名
            original_basename = os.path.basename(path)
            name, ext = os.path.splitext(original_basename)
            # 如果没有扩展名，尝试从Content-Type获取
            if not ext or len(ext) > 6:
                ext = self.get_extension_from_content_type(url)

            # 清理文件名，移除非法字符
            safe_name = re.sub(r'[^\w\-_\.]', '_', name)[:30]  # 限制长度
            if not safe_name or safe_name in ['.', '_']:
                safe_name = "media"

            # 生成唯一标识
            url_hash = hashlib.md5(url.encode('utf-8')).hexdigest()[:8]

            return f"{safe_name}_{url_hash}{ext}"

        except Exception as e:
            self.log_updated.emit(f"文件名生成异常: {e}")
            # 备用方案
            url_hash = hashlib.md5(url.encode('utf-8')).hexdigest()
            return f"media_{url_hash[:12]}.bin"

    def download_with_retry(self, url, local_path, max_retries=None):
        """带重试机制的下载"""
        if max_retries is None:
            max_retries = Config.MAX_RETRIES

        for attempt in range(max_retries):
            if not self.is_running:
                return False

            try:
                self.log_updated.emit(f" 尝试下载 (第{attempt + 1}次): {url}")
                response = requests.get(url, stream=True, timeout=Config.DOWNLOAD_TIMEOUT)
                response.raise_for_status()

                # 检查文件大小
                content_length = response.headers.get('content-length')
                if content_length and int(content_length) > Config.MAX_FILE_SIZE:
                    raise Exception(f"文件过大: {self.format_size(int(content_length))} (限制: {self.format_size(Config.MAX_FILE_SIZE)})")

                # 确保目录存在
                os.makedirs(os.path.dirname(local_path), exist_ok=True)

                # 下载文件
                downloaded_size = 0
                with open(local_path, 'wb') as f:
                    for chunk in response.iter_content(chunk_size=Config.CHUNK_SIZE):
                        if not self.is_running:
                            raise Exception("任务被用户中止")
                        if chunk:
                            f.write(chunk)
                            downloaded_size += len(chunk)

                self.stats['size'] += downloaded_size
                self.log_updated.emit(f" ✓ 下载成功: {self.format_size(downloaded_size)}")
                return True

            except Exception as e:
                error_msg = str(e)
                if attempt == max_retries - 1:
                    self.log_updated.emit(f" ✗ 下载失败 (已重试{max_retries}次): {error_msg}")
                    return False
                else:
                    self.log_updated.emit(f" ⚠ 下载失败，准备重试: {error_msg}")
                    time.sleep(1)

        return False

    def run(self):
        try:
            self.log_updated.emit("=" * 50)
            self.log_updated.emit("开始处理任务...")
            self.log_updated.emit(f"待处理文件数: {len(self.file_paths)}")

            all_media_info = []

            # 第一阶段：扫描所有文件，提取媒体链接
            for file_path in self.file_paths:
                if not self.is_running:
                    return

                self.log_updated.emit(f"\n📁 扫描文件: {os.path.basename(file_path)}")

                try:
                    with open(file_path, 'r', encoding='utf-8') as f:
                        content = f.read()

                    urls = self.extract_media_urls(content)
                    self.log_updated.emit(f" 发现 {len(urls)} 个媒体链接")

                    # 为每个URL创建MediaInfo对象
                    for url in urls:
                        filename = self.generate_unique_filename(url)
                        size = self.get_file_size(url) if not self.preview_only else "未检查"
                        media_info = MediaInfo(url, filename, "待下载", size)
                        all_media_info.append(media_info)

                except Exception as e:
                    self.log_updated.emit(f" ✗ 文件读取失败: {e}")
                    continue

            # 去重
            unique_media = {}
            for media in all_media_info:
                if media.url not in unique_media:
                    unique_media[media.url] = media

            self.media_list = list(unique_media.values())
            self.stats['total'] = len(self.media_list)

            # 发送媒体列表信号
            self.media_found.emit(self.media_list)

            if self.preview_only:
                self.log_updated.emit(f"\n预览完成，共发现 {len(self.media_list)} 个独立媒体文件")
                self.task_finished.emit("预览完成", True)
                return

            if not self.media_list:
                self.log_updated.emit("未发现任何媒体文件需要下载")
                self.task_finished.emit("未发现媒体文件", True)
                return

            self.log_updated.emit(f"\n开始下载 {len(self.media_list)} 个媒体文件...")
            self.log_updated.emit("=" * 30)

            # 第二阶段：下载媒体文件
            for i, media_info in enumerate(self.media_list):
                if not self.is_running:
                    self.log_updated.emit("\n❌ 任务被用户中止")
                    return

                progress = int((i / len(self.media_list)) * 100)
                self.progress_updated.emit(progress)
                self.log_updated.emit(f"\n[{i + 1}/{len(self.media_list)}] {media_info.filename}")

                # 为每个文件创建媒体目录
                #base_dir = os.path.dirname(self.file_paths)  # 使用第一个文件的目录
                #base_dir = os.path.dirname(self.file_paths[0])  # 使用第一个文件的目录
                #media_dir = os.path.join(base_dir, "media")
                #media_dir = os.path.join(base_dir, f"{md_name}+media") # 修改点




                # --- 修改开始：根据媒体链接所属的原始MD文件确定保存目录 ---
                # 假设 media_info.url 最初是从某个文件中提取的
                # 我们需要找到它属于哪个文件。这里简化处理：遍历所有文件，找到包含该URL的第一个文件。
                # 更优方案是在 extract_media_urls 时就记录来源文件。
                source_file_path = None
                for fp in self.file_paths:
                     try:
                         with open(fp, 'r', encoding='utf-8') as f:
                             content = f.read()
                         if media_info.url in content:
                             source_file_path = fp
                             break
                     except:
                         continue

                if source_file_path:
                     base_dir = os.path.dirname(source_file_path)
                     md_name = os.path.splitext(os.path.basename(source_file_path))[0]
                else:
                     # 如果找不到来源文件（理论上不应发生），回退到使用第一个文件的目录
                     self.log_updated.emit(f"  警告: 无法确定来源文件，使用默认目录")
                     base_dir = os.path.dirname(self.file_paths[0])
                     md_name = "default" # 或者使用其他默认名称

                media_dir = os.path.join(base_dir, f"{md_name}+media") # 使用 md文件名+media




                local_path = os.path.join(media_dir, media_info.filename)
                media_info.local_path = local_path

                if self.download_with_retry(media_info.url, local_path):
                    media_info.status = "✓ 成功"
                    self.stats['success'] += 1
                else:
                    media_info.status = "✗ 失败"
                    self.stats['failed'] += 1

                # 延时避免过于频繁的请求
                time.sleep(Config.DELAY_BETWEEN_DOWNLOADS)








            # 第三阶段：更新Markdown文件
            self.log_updated.emit("\n" + "=" * 30)
            self.log_updated.emit("开始更新Markdown文件...")

            for file_path in self.file_paths:
                if not self.is_running:
                    return

                try:
                    with open(file_path, 'r', encoding='utf-8') as f:
                        content = f.read()

                    # 替换所有成功下载的媒体链接
                    new_content = content
                    base_dir = os.path.dirname(file_path)
                    md_name = os.path.splitext(os.path.basename(file_path))[0] # 获取md文件名

                    for media_info in self.media_list:
                        if media_info.status == "✓ 成功":
                            # 计算相对路径
                            #rel_path = os.path.relpath(media_info.local_path, base_dir)
                            #rel_path = rel_path.replace('\\', '/')  # 统一使用正斜杠
                            #new_content = new_content.replace(media_info.url, rel_path)


                            # --- 修改开始：计算相对于当前MD文件的正确相对路径 ---
                            # media_info.local_path 是完整路径，例如 D:/path/to/file.md+media/image.jpg
                            # 我们需要计算从 base_dir (D:/path/to/) 到 media_info.local_path 的相对路径
                            try:
                                rel_path = os.path.relpath(media_info.local_path, base_dir)
                                rel_path = rel_path.replace('\\', '/')  # 统一使用正斜杠
                                new_content = new_content.replace(media_info.url, rel_path)
                                self.log_updated.emit(f"  更新链接: {media_info.url} -> {rel_path}")
                            except Exception as e:
                                self.log_updated.emit(f"  更新链接失败 {media_info.url}: {e}")
                            # --- 修改结束 ---


                    # 保存新文件
                    name, ext = os.path.splitext(file_path)
                    new_file_path = f"{name}_local{ext}"

                    with open(new_file_path, 'w', encoding='utf-8') as f:
                        f.write(new_content)

                    self.log_updated.emit(f" ✓ 已保存: {os.path.basename(new_file_path)}")

                except Exception as e:
                    self.log_updated.emit(f" ✗ 文件处理失败: {e}")

            # 完成
            self.progress_updated.emit(100)
            self.log_updated.emit("\n" + "=" * 50)
            self.log_updated.emit("📊 处理统计:")
            self.log_updated.emit(f" 总计: {self.stats['total']} 个文件")
            self.log_updated.emit(f" 成功: {self.stats['success']} 个")
            self.log_updated.emit(f" 失败: {self.stats['failed']} 个")
            self.log_updated.emit(f" 大小: {self.format_size(self.stats['size'])}")
            self.log_updated.emit("🎉 任务完成！")

            success = self.stats['failed'] == 0
            message = f"任务完成！成功: {self.stats['success']}, 失败: {self.stats['failed']}"
            self.task_finished.emit(message, success)

        except Exception as e:
            import traceback
            error_msg = f"严重错误: {e}\n{traceback.format_exc()}"
            self.log_updated.emit(f"\n❌ {error_msg}")
            self.task_finished.emit("任务失败，请检查日志", False)


class SettingsDialog(QDialog):
    """设置对话框"""
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("设置")
        self.setModal(True)
        self.initUI()

    def initUI(self):
        layout = QVBoxLayout()

        # 创建表单
        form_layout = QFormLayout()

        # 下载超时设置
        self.timeout_spin = QSpinBox()
        self.timeout_spin.setRange(5, 300)
        self.timeout_spin.setValue(Config.DOWNLOAD_TIMEOUT)
        self.timeout_spin.setSuffix(" 秒")
        form_layout.addRow("下载超时:", self.timeout_spin)

        # 重试次数设置
        self.retry_spin = QSpinBox()
        self.retry_spin.setRange(1, 10)
        self.retry_spin.setValue(Config.MAX_RETRIES)
        form_layout.addRow("重试次数:", self.retry_spin)

        # 下载延时设置
        self.delay_spin = QSpinBox()
        self.delay_spin.setRange(0, 5000)
        self.delay_spin.setValue(int(Config.DELAY_BETWEEN_DOWNLOADS * 1000))
        self.delay_spin.setSuffix(" 毫秒")
        form_layout.addRow("下载延时:", self.delay_spin)

        # 文件大小限制
        self.size_spin = QSpinBox()
        self.size_spin.setRange(1, 1000)
        self.size_spin.setValue(Config.MAX_FILE_SIZE // (1024 * 1024))
        self.size_spin.setSuffix(" MB")
        form_layout.addRow("文件大小限制:", self.size_spin)

        layout.addLayout(form_layout)

        # 按钮
        button_layout = QHBoxLayout()

        save_btn = QPushButton("保存")
        save_btn.clicked.connect(self.save_settings)
        button_layout.addWidget(save_btn)

        cancel_btn = QPushButton("取消")
        cancel_btn.clicked.connect(self.reject)
        button_layout.addWidget(cancel_btn)

        layout.addLayout(button_layout)
        self.setLayout(layout)

    def save_settings(self):
        Config.DOWNLOAD_TIMEOUT = self.timeout_spin.value()
        Config.MAX_RETRIES = self.retry_spin.value()
        Config.DELAY_BETWEEN_DOWNLOADS = self.delay_spin.value() / 1000.0
        Config.MAX_FILE_SIZE = self.size_spin.value() * 1024 * 1024

        # 保存到配置文件
        Config.save_to_file("config.json")

        # 修复：确保这两行在 save_settings 方法内部
        QMessageBox.information(self, "设置", "设置已保存！")
        self.accept()



class MediaPreviewDialog(QDialog):
    """媒体预览对话框"""
    def __init__(self, media_list, parent=None):
        super().__init__(parent)
        self.media_list = media_list
        self.setWindowTitle("媒体文件预览")
        self.setModal(True)
        self.resize(800, 600)
        self.initUI()

    def initUI(self):
        layout = QVBoxLayout()

        # 统计信息
        info_label = QLabel(f"发现 {len(self.media_list)} 个媒体文件")
        info_label.setFont(QFont("", 10, QFont.Bold))
        layout.addWidget(info_label)

        # 媒体列表
        self.media_list_widget = QListWidget()
        for media in self.media_list:
            item_text = f"{media.filename}\n URL: {media.url}\n 大小: {media.size}"
            self.media_list_widget.addItem(item_text)

        layout.addWidget(self.media_list_widget)

        # 按钮
        button_layout = QHBoxLayout()

        download_btn = QPushButton("开始下载")
        download_btn.clicked.connect(self.accept)
        button_layout.addWidget(download_btn)

        cancel_btn = QPushButton("取消")
        cancel_btn.clicked.connect(self.reject)
        button_layout.addWidget(cancel_btn)

        layout.addLayout(button_layout)
        self.setLayout(layout)


class App(QWidget):
    """主窗口UI（全面增强版）"""
    def __init__(self):
        super().__init__()
        self.setWindowTitle('MarkLocalize-md文件媒体本地化工具')
        self.setGeometry(200, 200, 1000, 700)
        self.file_paths = []
        self.worker_thread = None
        self.config_path = "config.json"

        # 加载配置
        Config.load_from_file(self.config_path)

        self.initUI()
        self.setup_timer()

    def initUI(self):
        main_layout = QHBoxLayout()

        # 左侧面板
        left_panel = self.create_left_panel()

        # 右侧面板（日志和媒体列表）
        right_panel = self.create_right_panel()

        # 分割器
        splitter = QSplitter(Qt.Horizontal)
        splitter.addWidget(left_panel)
        splitter.addWidget(right_panel)
        splitter.setStretchFactor(0, 1)
        splitter.setStretchFactor(1, 2)

        main_layout.addWidget(splitter)
        
        # 启用拖放
        self.setAcceptDrops(True)
        
        self.setLayout(main_layout)

    def create_left_panel(self):
        """创建左侧控制面板"""
        left_widget = QWidget()
        layout = QVBoxLayout()

        # 文件选择组
        file_group = QGroupBox("文件选择")
        file_layout = QVBoxLayout()

        self.label_file = QLabel('请选择 Markdown (.md) 文件')
        self.label_file.setAlignment(Qt.AlignCenter)
        self.label_file.setStyleSheet("QLabel { color: #666; font-style: italic; }")
        file_layout.addWidget(self.label_file)

        # 文件选择按钮
        btn_layout = QGridLayout()

        self.btn_select_single = QPushButton('选择单个文件')
        self.btn_select_single.clicked.connect(self.select_single_file)
        btn_layout.addWidget(self.btn_select_single, 0, 0)

        self.btn_select_multiple = QPushButton('选择多个文件')
        self.btn_select_multiple.clicked.connect(self.select_multiple_files)
        btn_layout.addWidget(self.btn_select_multiple, 0, 1)

        file_layout.addLayout(btn_layout)
        file_group.setLayout(file_layout)
        layout.addWidget(file_group)

        # 操作按钮组
        action_group = QGroupBox("操作")
        action_layout = QVBoxLayout()

        self.btn_preview = QPushButton('🔍 预览媒体文件')
        self.btn_preview.clicked.connect(self.preview_media)
        self.btn_preview.setEnabled(False)
        action_layout.addWidget(self.btn_preview)

        self.btn_start = QPushButton('🚀 开始下载')
        self.btn_start.clicked.connect(self.start_processing)
        self.btn_start.setEnabled(False)
        action_layout.addWidget(self.btn_start)

        self.btn_stop = QPushButton('⏹ 停止处理')
        self.btn_stop.clicked.connect(self.stop_processing)
        self.btn_stop.setEnabled(False)
        action_layout.addWidget(self.btn_stop)

        action_group.setLayout(action_layout)
        layout.addWidget(action_group)

        # 进度组
        progress_group = QGroupBox("进度")
        progress_layout = QVBoxLayout()

        self.progress_bar = QProgressBar()
        self.progress_bar.setValue(0)
        progress_layout.addWidget(self.progress_bar)

        self.status_label = QLabel("就绪")
        self.status_label.setAlignment(Qt.AlignCenter)
        progress_layout.addWidget(self.status_label)

        progress_group.setLayout(progress_layout)
        layout.addWidget(progress_group)

        # 工具按钮组
        tools_group = QGroupBox("工具")
        tools_layout = QVBoxLayout()

        self.btn_settings = QPushButton('⚙ 设置')
        self.btn_settings.clicked.connect(self.show_settings)
        tools_layout.addWidget(self.btn_settings)

        self.btn_save_log = QPushButton('💾 保存日志')
        self.btn_save_log.clicked.connect(self.save_log)
        tools_layout.addWidget(self.btn_save_log)

        self.btn_clear_log = QPushButton('🗑 清空日志')
        self.btn_clear_log.clicked.connect(self.clear_log)
        tools_layout.addWidget(self.btn_clear_log)

        tools_group.setLayout(tools_layout)
        layout.addWidget(tools_group)

        layout.addStretch()
        left_widget.setLayout(layout)
        return left_widget

    def create_right_panel(self):
        """创建右侧面板"""
        right_widget = QWidget()
        layout = QVBoxLayout()

        # 标签页式布局可以考虑，这里简化为垂直分割
        splitter = QSplitter(Qt.Vertical)

        # 日志区域
        log_group = QGroupBox("处理日志")
        log_layout = QVBoxLayout()

        self.log_box = QTextEdit()
        self.log_box.setReadOnly(True)
        self.log_box.setPlaceholderText("处理日志将显示在这里...")
        self.log_box.setFont(QFont("Consolas", 9))
        log_layout.addWidget(self.log_box)

        log_group.setLayout(log_layout)
        splitter.addWidget(log_group)

        # 媒体列表区域
        media_group = QGroupBox("媒体文件列表")
        media_layout = QVBoxLayout()

        self.media_list_widget = QListWidget()
        self.media_list_widget.setAlternatingRowColors(True)
        media_layout.addWidget(self.media_list_widget)

        media_group.setLayout(media_layout)
        splitter.addWidget(media_group)

        splitter.setStretchFactor(0, 2)
        splitter.setStretchFactor(1, 1)

        layout.addWidget(splitter)
        right_widget.setLayout(layout)
        return right_widget

    def setup_timer(self):
        """设置定时器用于更新状态"""
        self.timer = QTimer()
        self.timer.timeout.connect(self.update_status)
        self.timer.start(1000)  # 每秒更新一次

    def select_single_file(self):
        """选择单个文件"""
        file_path, _ = QFileDialog.getOpenFileName(
            self, "选择 Markdown 文件", "",
            "Markdown Files (*.md);;All Files (*)"
        )
        if file_path:
            self.file_paths = [file_path]
            self.update_file_display()

    def select_multiple_files(self):
        """选择多个文件"""
        file_paths, _ = QFileDialog.getOpenFileNames(
            self, "选择 Markdown 文件", "",
            "Markdown Files (*.md);;All Files (*)"
        )
        if file_paths:
            self.file_paths = file_paths
            # 修复前：self.update_file_display(self):
            self.update_file_display()  # 移除冒号和多余的self参数

    def update_file_display(self):
        """更新文件显示"""
        if len(self.file_paths) == 1:
            # 修复：添加缺少的右括号和索引
            filename = os.path.basename(self.file_paths[0])
            self.label_file.setText(f'已选择: {filename}')
        else:
            self.label_file.setText(f'已选择 {len(self.file_paths)} 个文件')

        self.btn_preview.setEnabled(True)
        self.btn_start.setEnabled(True)
        self.log_box.clear()
        self.media_list_widget.clear()
        self.progress_bar.setValue(0)

        # 显示选择的文件列表
        files_text = "准备处理以下文件:\n" + "\n".join([f"• {os.path.basename(f)}" for f in self.file_paths])
        self.log_box.append(files_text)


        # 修复base_dir处理
        base_dir = os.path.dirname(self.file_paths[0])  # 使用第一个文件的目录
        

    def preview_media(self):
        """预览媒体文件"""
        if not self.file_paths:
            QMessageBox.warning(self, "警告", "请先选择文件。")
            return

        self.set_buttons_enabled(False)
        self.log_box.clear()
        self.media_list_widget.clear()

        # 启动预览线程
        self.worker_thread = WorkerThread(self.file_paths, preview_only=True)
        self.worker_thread.log_updated.connect(self.update_log)
        self.worker_thread.media_found.connect(self.show_media_list)
        self.worker_thread.task_finished.connect(self.on_preview_finished)
        self.worker_thread.start()

    def start_processing(self):
        """开始处理"""
        if not self.file_paths:
            QMessageBox.warning(self, "警告", "请先选择文件。")
            return

        self.set_buttons_enabled(False)
        self.btn_stop.setEnabled(True)
        self.log_box.clear()
        self.progress_bar.setValue(0)

        # 启动处理线程
        self.worker_thread = WorkerThread(self.file_paths, preview_only=False)
        self.worker_thread.log_updated.connect(self.update_log)
        self.worker_thread.progress_updated.connect(self.update_progress)
        self.worker_thread.media_found.connect(self.show_media_list)
        self.worker_thread.task_finished.connect(self.on_task_finished)
        self.worker_thread.start()

    def stop_processing(self):
        """停止处理"""
        if self.worker_thread and self.worker_thread.isRunning():
            self.worker_thread.stop()
            self.log_box.append("正在停止任务...")
            self.btn_stop.setEnabled(False)

    def show_settings(self):
        """显示设置对话框"""
        dialog = SettingsDialog(self)
        dialog.exec_()

    def save_log(self):
        """保存日志到文件"""
        if not self.file_paths:
            QMessageBox.information(self, "提示", "没有日志内容可保存。")
            return

        file_path, _ = QFileDialog.getSaveFileName(
            self, "保存日志", "processing_log.txt",
            "Text Files (*.txt);;All Files (*)"
        )

        if file_path:
            try:
                with open(file_path, 'w', encoding='utf-8') as f:
                    f.write(self.log_box.toPlainText())
                QMessageBox.information(self, "成功", f"日志已保存到:\n{file_path}")
            except Exception as e:
                QMessageBox.critical(self, "错误", f"日志保存失败:\n{e}")


    def clear_log(self):
        """清空日志"""
        self.log_box.clear()
        self.media_list_widget.clear()








    def dragEnterEvent(self, event):
        """处理拖入事件"""
        if event.mimeData().hasUrls():
            # 检查是否所有拖入的都是文件
            for url in event.mimeData().urls():
                if not url.isLocalFile():
                    event.ignore()
                    return
            event.acceptProposedAction()
        else:
            event.ignore()

    def dropEvent(self, event):
        """处理放下事件"""
        if event.mimeData().hasUrls():
            file_paths = []
            for url in event.mimeData().urls():
                if url.isLocalFile():
                    file_path = url.toLocalFile()
                    # 检查文件扩展名是否为 .md
                    if file_path.lower().endswith('.md'):
                        file_paths.append(file_path)
            if file_paths:
                self.file_paths = file_paths
                self.update_file_display()
                event.acceptProposedAction()
            else:
                 QMessageBox.information(self, "信息", "拖放的文件中没有找到 .md 文件。")
                 event.ignore()
        else:
            event.ignore()

















    def show_media_list(self, media_list):
        """显示媒体文件列表"""
        self.media_list_widget.clear()
        for i, media in enumerate(media_list):
            status_icon = {"待下载": "⏳", "✓ 成功": "✅", "✗ 失败": "❌"}.get(media.status, "❓")
            item_text = f"{status_icon} {media.filename} ({media.size})"
            self.media_list_widget.addItem(item_text)

    def update_log(self, message):
        """更新日志"""
        self.log_box.append(message)
        # 自动滚动到底部
        scrollbar = self.log_box.verticalScrollBar()
        scrollbar.setValue(scrollbar.maximum())

    def update_progress(self, value):
        """更新进度条"""
        self.progress_bar.setValue(value)

    def update_status(self):
        """更新状态标签"""
        if self.worker_thread and self.worker_thread.isRunning():
            self.status_label.setText("处理中...")
        else:
            self.status_label.setText("就绪")

    def on_preview_finished(self, message, success):
        """预览完成"""
        self.set_buttons_enabled(True)
        self.worker_thread = None

    def on_task_finished(self, message, success):
        """任务完成"""
        self.set_buttons_enabled(True)
        self.btn_stop.setEnabled(False)
        self.worker_thread = None

        # 显示完成消息
        if success:
            QMessageBox.information(self, "成功", message)
        else:
            QMessageBox.warning(self, "完成", message)

    def set_buttons_enabled(self, enabled):
        """设置按钮状态"""
        self.btn_select_single.setEnabled(enabled)
        self.btn_select_multiple.setEnabled(enabled)
        self.btn_preview.setEnabled(enabled and bool(self.file_paths))
        self.btn_start.setEnabled(enabled and bool(self.file_paths))

    def closeEvent(self, event):
        """关闭事件"""
        if self.worker_thread and self.worker_thread.isRunning():
            reply = QMessageBox.question(
                self, '确认退出',
                '任务正在进行中，确定要退出吗？',
                QMessageBox.Yes | QMessageBox.No,
                QMessageBox.No
            )

            if reply == QMessageBox.Yes:
                self.worker_thread.stop()
                self.worker_thread.wait(5000)  # 等待最多5秒
            else:
                event.ignore()
                return

        # 保存配置
        Config.save_to_file(self.config_path)
        event.accept()


def main():
    """主函数"""
    app = QApplication(sys.argv)
    app.setApplicationName("MarkLocalize-md文件媒体本地化工具")
    app.setApplicationVersion("2.0")

    # 设置应用程序图标和样式
    app.setStyle('Fusion')

    # 创建并显示主窗口
    window = App()
    window.show()

    sys.exit(app.exec_())


if __name__ == '__main__':
    main()
